package com.ibeeking.gmc.global.g.rest.service.impl;


import com.ibeeking.found.common.constants.GlobalConstant;
import com.ibeeking.found.common.entity.DatabaseTemplateDTO;
import com.ibeeking.found.common.entity.DatasourceConfigDTO;
import com.ibeeking.found.common.entity.DictDTO;
import com.ibeeking.found.common.entity.IndustryFrontendDTO;
import com.ibeeking.found.common.enums.FrontendTypeEnum;
import com.ibeeking.found.common.enums.IndustryTypeEnum;
import com.ibeeking.found.common.utils.DateUtils;
import com.ibeeking.gmc.global.g.rest.service.IDatabaseTemplateService;
import com.ibeeking.gmc.global.g.rest.service.IDatasourceConfigService;
import com.ibeeking.gmc.global.g.rest.service.IDictValueService;
import com.ibeeking.gmc.global.service.common.constants.RedisKeyConstant;
import com.ibeeking.gmc.global.service.common.dos.IndustryFrontendDO;
import com.ibeeking.gmc.global.service.common.param.IndustryFrontendParam;
import com.ibeeking.gmc.global.service.common.vo.*;
import com.ibeeking.found.common.base.BaseDO;
import com.ibeeking.found.common.enums.ApplicationEnum;
import com.ibeeking.found.common.enums.PublishStatusEnum;
import com.ibeeking.found.common.utils.UserUtils;
import com.ibeeking.gmc.global.service.common.bo.DatasourceConfigBO;
import com.ibeeking.gmc.global.service.common.bo.DatabaseTemplateBO;
import com.ibeeking.gmc.global.service.common.dos.DatabaseTemplateDO;
import com.ibeeking.gmc.global.service.common.param.DatabaseTemplateParam;
import com.ibeeking.gmc.global.service.common.query.DatabaseTemplatePageQuery;
import com.ibeeking.gmc.global.service.common.query.DatabaseTemplateQuery;
import com.ibeeking.gmc.global.service.mapper.DatabaseTemplateMapper;
import com.ibeeking.gmc.global.service.mapper.IndustryFrontendMapper;
import com.ibeeking.nematos.core.utils.SpringBeanUtil;
import com.ibeeking.nematos.exception.BusinessException;
import com.ibeeking.nematos.log.utils.LogUtils;
import com.ibeeking.nematos.redis.annotation.CacheQuery;
import com.ibeeking.nematos.utils.bean.BeanUtil;
import com.ibeeking.nematos.utils.data.Collections3;
import com.ibeeking.nematos.utils.data.StringUtils;
import com.ibeeking.nematos.utils.data.TreeFastUtils;
import com.ibeeking.nematos.utils.id.IdGenerator;
import com.ibeeking.nematos.utils.json.JsonUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @ClassName DatabaseTemplateServiceImpl
 * @Description
 * @Author ibeeking
 * @Date 2021-03-02 09:07
 **/
@Service
public class DatabaseTemplateServiceImpl extends ServiceImpl<DatabaseTemplateMapper, DatabaseTemplateDO> implements IDatabaseTemplateService {

    @Resource
    private DatabaseTemplateMapper databaseTemplateMapper;
    @Resource
    private IndustryFrontendMapper industryFrontendMapper;
    @Resource
    private IDatasourceConfigService templateDatabaseConfigServiceImpl;
    @Resource
    private IDictValueService dictValueServiceImpl;

    @Override
    public Page<DatabaseTemplatePageVO> pageList(DatabaseTemplatePageQuery query) {
        LambdaQueryWrapper<DatabaseTemplateDO> queryWrapper = new LambdaQueryWrapper<DatabaseTemplateDO>()
                .orderByAsc(DatabaseTemplateDO::getSort)
                .orderByDesc(BaseDO::getCreateTime)
                .eq(null != query.getPublishStatus(), DatabaseTemplateDO::getPublishStatus, query.getPublishStatus())
                .eq(null != query.getDbConfigId(), DatabaseTemplateDO::getDbConfigId, query.getDbConfigId())
                .eq(StringUtils.isNotBlank(query.getIndustry()), DatabaseTemplateDO::getIndustry, query.getIndustry())
                .eq(StringUtils.isNotBlank(query.getDbName()), DatabaseTemplateDO::getDbName, query.getDbName())
                .eq(StringUtils.isNotBlank(query.getApplication()), DatabaseTemplateDO::getApplication, query.getApplication());
        Page<DatabaseTemplateDO> pages = databaseTemplateMapper.selectPage(new Page<>(query.getPageNum(), query.getPageSize()), queryWrapper);
        Page<DatabaseTemplatePageVO> result = BeanUtil.convertPage(pages, DatabaseTemplatePageVO.class);
        List<DatabaseTemplatePageVO> listVOS = result.getRecords();
        if (!Collections3.isEmpty(listVOS)) {
            List<Long> dbConfigIds = listVOS.parallelStream().map(DatabaseTemplatePageVO::getDbConfigId).distinct().collect(Collectors.toList());
            Map<Long, String> dbConfigNames = configNames(dbConfigIds);
            listVOS.stream().forEach(s -> {
                s.setIndustryName(IndustryTypeEnum.getNameByCode(s.getIndustry()));
                s.setApplicationName(s.getApplication().getDescription());
                if (dbConfigNames.containsKey(s.getDbConfigId())) {
                    s.setDbConfigName(dbConfigNames.get(s.getDbConfigId()));
                }
            });
            result.setRecords(listVOS);
        }
        return result;
    }

    @Override
    public Boolean add(DatabaseTemplateParam param) {
        DatabaseTemplateDO databaseTemplateDO = BeanUtil.convertBean(param, DatabaseTemplateDO.class);
        databaseTemplateDO.setApplication(param.getApplication().name());
        if (!checkUnique(databaseTemplateDO)) {
            throw new BusinessException("当前模板配置已存在");
        }
        databaseTemplateDO.setCreateBy(UserUtils.getUserId());
        databaseTemplateDO.setCreateTime(LocalDateTime.now());
        databaseTemplateDO.setModifyTime(LocalDateTime.now());
        databaseTemplateMapper.insert(databaseTemplateDO);
        return true;
    }

    @Override
    public Boolean modify(DatabaseTemplateParam param) {
        DatabaseTemplateDO databaseTemplateDO = BeanUtil.convertBean(param, DatabaseTemplateDO.class);
        databaseTemplateDO.setApplication(getBean().queryById(param.getId()).getApplication().name());
        //if (!checkUnique(databaseTemplateDO)) {
        //    throw new BusinessException("当前模板配置已存在");
       // }
        databaseTemplateDO.setModifyBy(UserUtils.getUserId());
        databaseTemplateDO.setModifyTime(LocalDateTime.now());
        databaseTemplateMapper.updateById(databaseTemplateDO);
        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean copyFromIndustry(String fromIndustry, String toIndustry){
        List<DatabaseTemplateDO> copyDOS = new ArrayList<>();
        List<DatabaseTemplateDO> databaseTemplateDos = databaseTemplateMapper.selectList(new LambdaQueryWrapper<DatabaseTemplateDO>()
                .eq(DatabaseTemplateDO::getIndustry, fromIndustry));
        if(Collections3.isNotEmpty(databaseTemplateDos)){
            copyDOS = databaseTemplateDos.stream().map(s->{
                DatabaseTemplateDO  copyDO = BeanUtil.convertBean(s, DatabaseTemplateDO.class);
                copyDO.setId(IdGenerator.getId());
                copyDO.setCreateTime(LocalDateTime.now());
                copyDO.setModifyTime(LocalDateTime.now());
                copyDO.setIndustry(toIndustry);
                return copyDO;
            }).collect(Collectors.toList());
            return databaseTemplateMapper.insertBatchSomeColumn(copyDOS) > 0;
        }
        return false;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean clearTemplateDatabase(String industry){
        if(StringUtils.isEmpty(industry)) throw new BusinessException("行业参数不能为空！");
        List<DatabaseTemplateDO> databaseTemplateDos = databaseTemplateMapper.selectList(new LambdaQueryWrapper<DatabaseTemplateDO>()
                .eq(DatabaseTemplateDO::getIndustry, industry));
        if(Collections3.isNotEmpty(databaseTemplateDos)){
            return databaseTemplateMapper.delete(new LambdaQueryWrapper<DatabaseTemplateDO>().eq(DatabaseTemplateDO::getIndustry, industry)) > 0;
        }
        return false;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean changeDataConfig(String industry, Long dbConfigId) {
        List<DatabaseTemplateDO> databaseTemplateDos = databaseTemplateMapper.selectList(new LambdaQueryWrapper<DatabaseTemplateDO>()
                .eq(DatabaseTemplateDO::getIndustry, industry));
        if(Collections3.isNotEmpty(databaseTemplateDos)) {
            LambdaQueryWrapper<DatabaseTemplateDO> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(DatabaseTemplateDO::getIndustry, industry);
            DatabaseTemplateDO copTemplateDO = new DatabaseTemplateDO();
            copTemplateDO.setDbConfigId(dbConfigId);
            copTemplateDO.setModifyTime(LocalDateTime.now());
            return databaseTemplateMapper.update(copTemplateDO, queryWrapper) > 0;
        }
        return false;
    }

    @Override
    public DatabaseTemplateVO view(Long id) {
        DatabaseTemplateBO databaseTemplateBO = getBean().queryById(id);
        DatabaseTemplateVO databaseTemplateVO = BeanUtil.convertBean(databaseTemplateBO, DatabaseTemplateVO.class);
        databaseTemplateVO.setDbConfigName(configNames(Arrays.asList(id)).get(databaseTemplateVO.getDbConfigId()));
        databaseTemplateVO.setIndustryName(IndustryTypeEnum.getNameByCode(databaseTemplateVO.getIndustry()));
        return databaseTemplateVO;
    }

    @Override
    public DatabaseTemplateBO queryById(Long id) {
        DatabaseTemplateDO databaseTemplateDO = databaseTemplateMapper.selectById(id);
        DatabaseTemplateBO databaseTemplateBO = BeanUtil.convertBean(databaseTemplateDO, DatabaseTemplateBO.class);
        databaseTemplateBO.setApplication(ApplicationEnum.valueOf(databaseTemplateDO.getApplication()));
        return databaseTemplateBO;
    }

    @Override
    public Boolean changeStatus(Long id, Integer status) {
        DatabaseTemplateDO databaseTemplateDO = new DatabaseTemplateDO();
        databaseTemplateDO.setId(id);
        databaseTemplateDO.setModifyBy(UserUtils.getUserId());
        databaseTemplateDO.setModifyTime(LocalDateTime.now());
        databaseTemplateDO.setPublishStatus(status);
        return databaseTemplateMapper.updateById(databaseTemplateDO) > 0;
    }

    @Transactional(rollbackFor = {Exception.class})
    @Override
    public Boolean del(Long id) {
        //删除数据库
        DatabaseTemplateBO databaseTemplateBO = getBean().queryById(id);
        if (PublishStatusEnum.ENABLE.getValue().equals(databaseTemplateBO.getPublishStatus())) {
            throw new BusinessException("请先禁用后再删除");
        }
        return databaseTemplateMapper.deleteById(id) > 0;
    }

    @Override
    public List<DatabaseTemplateVO> list(DatabaseTemplateQuery query) {
        LambdaQueryWrapper<DatabaseTemplateDO> queryWrapper = new LambdaQueryWrapper<DatabaseTemplateDO>()
                .orderByAsc(DatabaseTemplateDO::getSort)
                .orderByDesc(BaseDO::getCreateTime)
                .eq(DatabaseTemplateDO::getPublishStatus, PublishStatusEnum.ENABLE.getValue())
                .eq(StringUtils.isNotBlank(query.getIndustry()), DatabaseTemplateDO::getIndustry, query.getIndustry())
                .eq(StringUtils.isNotBlank(query.getDbName()), DatabaseTemplateDO::getDbName, query.getDbName())
                .eq(StringUtils.isNotBlank(query.getApplication()), DatabaseTemplateDO::getApplication, query.getApplication());
        List<DatabaseTemplateDO> databaseTemplateDos = databaseTemplateMapper.selectList(queryWrapper);
        List<DatabaseTemplateVO> result = JsonUtils.jsonToList(databaseTemplateDos, DatabaseTemplateVO.class);
        if (!Collections3.isEmpty(result)) {
            Map<Long, String> dbConfigNames = configNames(result.parallelStream().map(DatabaseTemplateVO::getDbConfigId).distinct().collect(Collectors.toList()));
            result.stream().filter(s -> dbConfigNames.containsKey(s.getDbConfigId()))
                    .forEach(s -> {
                s.setDbConfigName(dbConfigNames.get(s.getDbConfigId()));
                s.setIndustryName(IndustryTypeEnum.getNameByCode(s.getIndustry()));
            });
        }
        return result;
    }


    @Override
    public List<IndustryFrontendDTO> quertIndustryFrontend(String industry, String frontend){
        List<IndustryFrontendDO> entityDOS = industryFrontendMapper.selectList(new LambdaQueryWrapper<IndustryFrontendDO>()
                .eq(StringUtils.isNotEmpty(industry),IndustryFrontendDO::getIndustry, industry)
                .eq(StringUtils.isNotEmpty(frontend),IndustryFrontendDO::getFrontend, frontend));
        return JsonUtils.jsonToList(entityDOS, IndustryFrontendDTO.class);
    }

    @Override
    public IndustryFrontendVO viewIndustryFrontendVisible(String industry){
        IndustryFrontendVO results = new IndustryFrontendVO();
        results.setId(IdGenerator.getId());
        results.setIndustry(industry);
        if(StringUtils.isEmpty(industry)) throw new BusinessException("industry不能为空");
        List<IndustryFrontendDO> entityDOS = industryFrontendMapper.selectList(new LambdaQueryWrapper<IndustryFrontendDO>().eq(IndustryFrontendDO::getIndustry, industry));
        if(Collections3.isNotEmpty(entityDOS)){
            List<String> frontends = new ArrayList<>();
            entityDOS.parallelStream().forEach(s->{
                frontends.add(s.getFrontend());
            });
            results.setFrontendList(frontends);
        }
        LogUtils.info("listIndustryFrontendVisible >>>>> {}", JsonUtils.toJsonStr(results));
        return results;
    }

    @Transactional(rollbackFor = {Exception.class})
    @Override
    public Boolean modifyAndAddIndustryFrontend(IndustryFrontendParam param) {
        LogUtils.info("IndustryFrontendParam >>>>> {}", JsonUtils.toJsonStr(param));
        if(param == null) throw new BusinessException("读取参数为空");
        String industry = param.getIndustry();
        if(StringUtils.isEmpty(industry)) throw new BusinessException("industry不能为空");
        industryFrontendMapper.delete(new LambdaQueryWrapper<IndustryFrontendDO>().eq(IndustryFrontendDO::getIndustry, industry));
        List<String> frontendList = param.getFrontendList();
        List<IndustryFrontendDO> entityDOS = new ArrayList<>();
        if(Collections3.isNotEmpty(frontendList)){
            frontendList.parallelStream().forEach(s->{
                IndustryFrontendDO entityDO = new IndustryFrontendDO();
                entityDO.setIndustry(param.getIndustry());
                entityDO.setFrontend(s.toLowerCase());
                entityDOS.add(entityDO);
            });
        }
        if(Collections3.isNotEmpty(entityDOS)){
            return industryFrontendMapper.insertBatchSomeColumn(entityDOS) >0;
        }
        return false;
    }

    @Override
    public Boolean hasChild(Long parentId) {
        return databaseTemplateMapper.selectCount(new LambdaQueryWrapper<>(DatabaseTemplateDO.class)
                .eq(DatabaseTemplateDO::getDbConfigId, parentId)
        ) > 0;
    }

    @Override
    public List<DatabaseTemplateDTO> listByIndustry(String industry){
        List<DatabaseTemplateDTO> resultDTOS = new ArrayList<>();
        LambdaQueryWrapper<DatabaseTemplateDO> queryWrapper = new LambdaQueryWrapper<DatabaseTemplateDO>()
                .eq(DatabaseTemplateDO::getPublishStatus, PublishStatusEnum.ENABLE.getValue())
                .eq(DatabaseTemplateDO::getIndustry, industry);
        List<DatabaseTemplateDO> entityDOs = databaseTemplateMapper.selectList(queryWrapper);
        if(Collections3.isNotEmpty(entityDOs)){
            Long dbConfigId = entityDOs.get(0).getDbConfigId();
            DatasourceConfigDTO datasourceConfig = templateDatabaseConfigServiceImpl.viewById(dbConfigId);
            resultDTOS = entityDOs.stream().map(s->{
                DatabaseTemplateDTO entityDTO = BeanUtil.convertBean(s, DatabaseTemplateDTO.class);
                entityDTO.setDatasourceConfig(datasourceConfig);
                return entityDTO;
            }).collect(Collectors.toList());
        }
        return resultDTOS;
    }

    @Override
    public List<DatabaseTemplateBO> queryByIndustry(String industry){
        LambdaQueryWrapper<DatabaseTemplateDO> queryWrapper = new LambdaQueryWrapper<DatabaseTemplateDO>()
                .eq(DatabaseTemplateDO::getPublishStatus, PublishStatusEnum.ENABLE.getValue())
                .eq(DatabaseTemplateDO::getIndustry, industry);
        List<DatabaseTemplateDO> databaseTemplateDos = databaseTemplateMapper.selectList(queryWrapper);
        return JsonUtils.jsonToList(databaseTemplateDos, DatabaseTemplateBO.class);
    }

    @Override
    public List<DatabaseTemplateBO> queryByApplicationNames(String industry, List<String> applications) {
        if (Collections3.isEmpty(applications)) {
            return Collections3.emptyList();
        }
        LambdaQueryWrapper<DatabaseTemplateDO> queryWrapper = new LambdaQueryWrapper<DatabaseTemplateDO>()
                .eq(DatabaseTemplateDO::getPublishStatus, PublishStatusEnum.ENABLE.getValue())
                .eq(DatabaseTemplateDO::getIndustry, industry)
                .in(DatabaseTemplateDO::getApplication, applications);
        List<DatabaseTemplateDO> databaseTemplateDos = databaseTemplateMapper.selectList(queryWrapper);
        return JsonUtils.jsonToList(databaseTemplateDos, DatabaseTemplateBO.class);
    }

    @Override
    public List<DatabaseTemplateBO> queryByIds(List<Long> ids) {
        if (Collections3.isEmpty(ids)) {
            return Collections3.emptyList();
        }
        LambdaQueryWrapper<DatabaseTemplateDO> queryWrapper = new LambdaQueryWrapper<DatabaseTemplateDO>()
                .eq(DatabaseTemplateDO::getPublishStatus, PublishStatusEnum.ENABLE.getValue())
                .in(DatabaseTemplateDO::getId, ids);
        List<DatabaseTemplateDO> databaseTemplateDos = databaseTemplateMapper.selectList(queryWrapper);
        return JsonUtils.jsonToList(databaseTemplateDos, DatabaseTemplateBO.class);
    }

    @CacheQuery(cacheName = RedisKeyConstant.INDUSTRY_TREE_LIST)
    @Override
    public List<DatabaseTemplateIndustryTreeVO> queryTemplateDatabaseIndustryTreeList(){
        List<DatabaseTemplateIndustryVO> databaseTemplateIndustryVOS = getBean().templateDatabaseIndustry();
        List<DatabaseTemplateIndustryTreeVO> result = new ArrayList<>();
        if(Collections3.isNotEmpty(databaseTemplateIndustryVOS)) {
            databaseTemplateIndustryVOS.stream().sorted(Comparator.comparing(DatabaseTemplateIndustryVO::getSort)).forEach(typeVO -> {
                DatabaseTemplateIndustryTreeVO treeVO = BeanUtil.convertBean(typeVO, DatabaseTemplateIndustryTreeVO.class);
                treeVO.setId(typeVO.getCode());
                treeVO.setCode(typeVO.getCode());
                treeVO.setParentCode("all");
                treeVO.setParentId("all");
                result.add(treeVO);
            });
        }
        return TreeFastUtils.listToTree(result, "all");
    }

    @Override
    public List<IndustryFrontendTreeVO> queryIndustryFrontendTreeList(String industry){
        List<IndustryFrontendDO> entityDOS = industryFrontendMapper.selectList(
                new LambdaQueryWrapper<IndustryFrontendDO>()
                        .eq(IndustryFrontendDO::getIndustry, industry)
        );

        if(Collections3.isEmpty(entityDOS)) return null;
        List<IndustryFrontendTreeVO> result = new ArrayList<>();

        entityDOS.stream().forEach(typeVO -> {
            IndustryFrontendTreeVO treeVO = BeanUtil.convertBean(typeVO, IndustryFrontendTreeVO.class);
            treeVO.setId(typeVO.getId().toString());
            treeVO.setCode(typeVO.getFrontend());
            treeVO.setName(FrontendTypeEnum.getNameByCode(typeVO.getFrontend()));
            treeVO.setParentCode("all");
            treeVO.setParentId("all");
            result.add(treeVO);
        });
        return TreeFastUtils.listToTree(result, "all");
    }

    @CacheQuery(cacheName = RedisKeyConstant.INDUSTRY_LIST)
    @Override
    public List<DatabaseTemplateIndustryVO> templateDatabaseIndustry() {
        List<DictDTO> industryDictDTOS = dictValueServiceImpl.queryDictByType(GlobalConstant.GLOBAL_INDUSTRY_TYPE_KEY);
        List<DatabaseTemplateIndustryVO> result = new ArrayList<>();
        if(Collections3.isNotEmpty(industryDictDTOS)){
            industryDictDTOS.stream().sorted(Comparator.comparing(DictDTO::getSort)).forEach(s->{
                DatabaseTemplateIndustryVO industryVO = new DatabaseTemplateIndustryVO();
                industryVO.setCode(s.getValue());
                industryVO.setName(s.getLabel());
                industryVO.setSort(s.getSort());
                result.add(industryVO);
            });
        }
        return result;
    }

    @CacheQuery(cacheName = RedisKeyConstant.FRONT_END_LIST)
    @Override
    public List<FrontendTypeVO> frontEndType() {
        List<FrontendTypeVO> result = new ArrayList<>();
        FrontendTypeVO frontendTypeVO = null;
        for (FrontendTypeEnum application : FrontendTypeEnum.values()) {
            if(!application.getCode().equalsIgnoreCase(FrontendTypeEnum.GLOBAL.getCode())) {
                frontendTypeVO = new FrontendTypeVO();
                frontendTypeVO.setCode(application.getCode());
                frontendTypeVO.setName(application.getName());
                result.add(frontendTypeVO);
            }
        }
        return result;
    }

    @Override
    public List<ApplicationVO> application() {
        List<ApplicationVO> result = new ArrayList<>();
        ApplicationVO applicationVO = null;
        for (ApplicationEnum application : ApplicationEnum.values()) {
            applicationVO = new ApplicationVO();
            applicationVO.setValue(application.name());
            applicationVO.setDesc(application.getDescription());
            result.add(applicationVO);
        }
        return result;
    }

    @Override
    public List<ApplicationVO> usableApplication(String industry) {
        List<ApplicationVO> application = getBean().application();
        if (Collections3.isEmpty(application)) {
            return Collections3.emptyList();
        }

        List<DatabaseTemplateDO> databaseTemplateDos = databaseTemplateMapper.selectList(
                new LambdaQueryWrapper<>(DatabaseTemplateDO.class).eq(DatabaseTemplateDO::getIndustry, industry)
        );
        List<String> haves = Collections3.emptyList();
        if (!Collections3.isEmpty(databaseTemplateDos)) {
            haves = databaseTemplateDos.stream().map(DatabaseTemplateDO::getApplication).distinct().collect(Collectors.toList());
        }

        List<String> finalHaves = haves;
        return application.stream().filter(s -> !finalHaves.contains(s.getValue())).collect(Collectors.toList());
    }

    private Boolean checkUnique(DatabaseTemplateDO databaseDO) {
        Integer count = databaseTemplateMapper.selectCount(new LambdaQueryWrapper<>(DatabaseTemplateDO.class)
                .ne(null != databaseDO.getId(), DatabaseTemplateDO::getId, databaseDO.getId())
                .eq(DatabaseTemplateDO::getDbConfigId, databaseDO.getDbConfigId())
                .and(
                        Wrapper -> Wrapper
                                .eq(StringUtils.isNotBlank(databaseDO.getDbName()), DatabaseTemplateDO::getDbName, databaseDO.getDbName())
                                .or()
                                .eq(StringUtils.isNotBlank(databaseDO.getApplication()), DatabaseTemplateDO::getApplication, databaseDO.getApplication())
                )
        );
        return 0 == count;
    }

    private Map<Long, String> configNames(List<Long> ids) {
        List<DatasourceConfigBO> configBos = templateDatabaseConfigServiceImpl.selectNameByIds(ids);
        if (Collections3.isEmpty(configBos)) {
            return Collections3.emptyMap();
        }
        return configBos.parallelStream().collect(Collectors.toMap(DatasourceConfigBO::getId, DatasourceConfigBO::getName, (s, a) -> a));
    }

    private static IDatabaseTemplateService getBean() {
        return SpringBeanUtil.getBean(IDatabaseTemplateService.class);
    }
}
